/**
 * Led.h
 *
 * @autor: Bematech S.A.
 */

#ifndef __BILBAO_LED_LED_CONTROLLER_CLASS_H__
#define __BILBAO_LED_LED_CONTROLLER_CLASS_H__

#include "bilbao/types.h"
#include "bilbao/lang/Thread.h"
#include "bilbao/lang/Mutex.h"

#define T_LEDS int

#define L_APAGADO 0
#define L_ACESO 1
#define L_PISCANDO 2

enum E_LEDS
{
	L_SUP = 0x0020, //SUP
	L_PAR = 0x0010, //PAR
	L_SEF = 0x0004, //SEF
	L_CEL = 0x0008, //AC
	L_PAF = 0x0002, //PAF
	L_OPR = 0x0001  //OPR
};

/**
 * @brief Singleton responsável por controlar os LEDs do equipamento.
 *
 * Estrutura responsável por gerenciar o manipulamento dos leds do equipamento SAT.
 * Os leds são manipulados através de um arquivo que está localizado em /dev/avila_led.
 * Temos controle sobre 6 dos 7 leds existentes no equipamento. São eles:
 *  - SUP:
 *  - PAR:
 *  - SEF: 
 *  - CEF: 
 *  - PAF: 
 *  - OPR:
 * O s�timo led � o LIG que indica apenas se o equipamento est� ligado.
 * Est�o dispostos nesta ordem da esquerda para direita. A manipula��o deve ser feita
 * bit a bit, onde o bit 0(zero) acende o led e o bit 1(um) apaga-o.
 *
 * No terminal utilizamos o seguinte comando para manipul�-los:
 *  printf "\x00" > /dev/avila_led - Acende todos os leds
 *  printf "\xFF" > /dev/avila_led - Apaga todos os leds
 */
namespace bilbao
{
	namespace led
	{
		enum E_LEDSTATE
		{
			E_TURN_OFF = 0,
			E_TURN_ON = 1,
			E_TURN_BLINK = 2
		};

		class LedController
			: public lang::Thread
		{
		public:
			/**
			 * Destrutor
			 */
			virtual ~LedController( void );

			static LedController* getInstance( void );

			/** @override
			 */
			void run( void );

			/**
			 * O método ligar consiste em alterar o estado do led para L_ACESO.
			 * Este método pode ser chamado passando um ou mais leds. É feito uma verificação
			 * bit a bit de quais leds serão ligados. De acordo como eles estão mapeados no
			 * enum E_LEDS.
			 *
			 * Exemplo:
			 *   turnOn( L_PAF | L_SEF ); //Liga o led do PAF e o led da SEFAZ
			 *
			 * @param leds - Leds a serem desligados.
			 */
			void turnOn( int leds );

			/**
			 *
			 */
			void turnOff( int leds );

			/**
			 *
			 */
			void blink( int leds );

			/**
			 *
			 */
			void print( void );

			/*
			 *
			 */
			void finalize( void );

		private:
			/**
			 *
			 */
			static LedController* _instance;

			/**
			 * File descriptor =p
			 */
			int fd;
			/**
			 * Armazena o estado dos leds
			 */
			int estado_leds[6];
			/**
			 * Thread...
			 */
			pthread_t thread;
			/**
			 *
			 */
			pthread_mutex_t mutex;

			/**
			 * Construtor Padrão
			 */
			LedController( void );

			/**
			 *
			 */
			void setStateLeds( int, E_LEDSTATE );

		}; //class LedController
	} //namespace led
} //namespace bilbao

#endif //__BILBAO_LED_LED_CONTROLLER_CLASS_H__
